package edu.ucsd.irods;

import java.io.IOException;

import edu.sdsc.grid.io.GeneralFile;
import edu.sdsc.grid.io.irods.IRODSAccount;
import edu.sdsc.grid.io.irods.IRODSFile;
import edu.sdsc.grid.io.irods.IRODSFileSystem;

public class IRODSOperation {
	/*
	 * Same as the createNewInitalDirectory but create 1 directory at the time
	 */
	public static void createInitalDirectory (String base) throws Exception {
		
		// recursively create folder to match the given folder
		String[] folder = base.split("/");
		
		int index = 1;
		StringBuffer baseCurrent = new StringBuffer("/"); // start at root
		boolean stop = false;
		
		// find the first folder to start create folder	
		while ( !stop ) {
			
			IRODSAccount irodsAccount = createNewIRODSAccount( new String (baseCurrent) );
			IRODSFileSystem fileSystem = new IRODSFileSystem( irodsAccount);
			
			IRODSFile file = new IRODSFile(fileSystem, "." ); // plus empty folder, so it seems
			
			if ( !file.exists() || index >= folder.length ) {
				stop = true;				
			}
			else {
				baseCurrent.append(  folder[index] + "/" );	// can't use separator since this is on the server
				index ++;
			}
			
			fileSystem.close();
		}
		
//		System.out.println ("BaseCurrent: " + baseCurrent);
		while ( index < folder.length ){
			
			createDir(  upOneLevelDirectory (new String(baseCurrent), folder[index-1] ) ,folder[index-1] );
			baseCurrent.append(folder[index] + "/");
			index++;
		}
	}
	
	/*
	 * Get up one level directory. ie /a/b/c/ -> /a/b/ 
	 */
	private static String upOneLevelDirectory (String base, String lastFolder){
		String result = base.replaceAll(lastFolder + "/", "");
//		System.out.println (result);
		return result;
	}
	
	/*
	 * Try to create many level at once. We're using this
	 */
	public static void createNewInitalDirectory (String base ) throws Exception {
		
		IRODSAccount irodsAccount = createNewIRODSAccount("/");
		IRODSFileSystem fileSystem = new IRODSFileSystem( irodsAccount);
		
		IRODSFile file = new IRODSFile(fileSystem, base ); // plus empty folder, so it seems
		
		// Create dir at initial
		System.out.println("Make dir successful? " + file.mkdirs());
		
		//test
		System.out.println ("create many level at once: " + file.getAbsolutePath() );
		System.out.println ("Exist: " + file.exists() );
		
		fileSystem.close();
	}
	
	public static boolean isExist (String base ) throws Exception{
		
		IRODSAccount irodsAccount = createNewIRODSAccount(base);
		IRODSFileSystem fileSystem = new IRODSFileSystem( irodsAccount);
		
		IRODSFile file = new IRODSFile(fileSystem, "." ); // plus current folder
		
//		System.err.println ("Folder now: '" + file.getAbsolutePath() + "'");
		
		fileSystem.close();
		
		return file.exists() ;
	}
	
	/*
	 * Return true if the deletion is successful
	 */
	public static boolean deleteFile (String path) throws NullPointerException, IOException {
		
		boolean result = false;
		
//		IRODSAccount irodsAccount = createNewIRODSAccount( path );
		IRODSAccount irodsAccount = createNewIRODSAccount( "/");
		IRODSFileSystem fileSystem = new IRODSFileSystem (irodsAccount );
		
		IRODSFile file = new IRODSFile( fileSystem, path );
	
		System.out.println ("File exists before ? " + file.exists());
		
		if (file.delete() ) result = true;
//		IRODSFile tempFile = new IRODSFile(fileSystem, "/CCDBProdZone/home/CCDB_DATA_USER/trashcan/" + System.currentTimeMillis() );
//		tempFile.createNewFile();
//		if (file.renameTo(tempFile) ) result = true;
		
		System.out.println ("File exists after ? " + file.exists());
		
		fileSystem.close();
		
		return result; 
	}
	
	public static void moveFile (String sourceFile, String destinationFile ) throws NullPointerException, IOException {
		
		// special case in which sourceFile and destinationFile is the same
		if ( sourceFile.equalsIgnoreCase(destinationFile) ) { 
			System.out.println ("Move file to the same folder. Nothing done");
			return;
		}
		
		IRODSAccount irodsAccount = createNewIRODSAccount("/");
		IRODSFileSystem fileSystem = new IRODSFileSystem(irodsAccount);
		
		IRODSFile fileSource = new IRODSFile(fileSystem, sourceFile);
		IRODSFile fileDestination = new IRODSFile(fileSystem, destinationFile);
		
		// copy then delete the file
		fileDestination.copyFrom(fileSource);
		fileSource.delete();
		
		// test
		System.out.println ("File source exsit ? " + fileSource.exists());
		System.out.println ("File source exsit ? " + fileDestination.exists());
		
		fileSystem.close();		
	}
	
	/*
	 * Create a directory on IRODS account 
	 * 
	 * @param	base	your base directory
	 * @param	folder	the folder name 
	 */
	public static boolean createDir (String base, String folder ) throws Exception {
		
        try
        {
             for(int j=0;j<2;j++){
            	 System.out.println("CreateDIR Base:"+base+"   Folder:"+folder);
	             IRODSAccount irodAccount = createNewIRODSAccount(base);
	             IRODSFileSystem  srbFileSystem = new IRODSFileSystem(irodAccount);

	             IRODSFile irodsFile = new IRODSFile(srbFileSystem, folder);
	             System.out.println("Creating folder:"+irodsFile.getAbsolutePath());
	             
	             System.out.println("IRODS file exists:"+irodsFile.exists());
	             if(!irodsFile.exists())
	             {
	                System.err.println(irodsFile.mkdir());
	                System.err.println("IRODS DIR:"+irodsFile.getAbsolutePath()+" created");
	             }
	             else
	             {
	                 System.err.println("DIR:"+irodsFile.getAbsolutePath()+" already exists!");
	             }
	             srbFileSystem.close();
             }
             return true;
        }
        catch(Exception e)
        {
            e.printStackTrace();
            throw new Exception("CANNOT create a IRODS directory: "+e.getMessage());
        }
	}

	public static GeneralFile[] getListFiles (String base) throws NullPointerException, IOException {
		
		GeneralFile[] result = null;
		
		IRODSAccount irodsAccount = createNewIRODSAccount(base);
		IRODSFileSystem fileSystem = new IRODSFileSystem( irodsAccount);
		
		IRODSFile file = new IRODSFile(fileSystem, "." ); // plus current folder
		
//		System.out.println ("Is file: " + file.getAbsolutePath() + " is directory: " + file.isDirectory() ) ;
		
		if ( !file.isDirectory() || !file.exists()) {
			System.out.println ("RESULT FAIL. file directory: " + file.isDirectory() + ". File exist: " +  file.exists() );
			return result;
		}
		result = file.listFiles();
		fileSystem.close();
		
		return result;
	}
	
	public static IRODSAccount createNewIRODSAccount (String base){
		return new IRODSAccount(IRODSConfiguration.SERVER , IRODSConfiguration.PORT, 
				IRODSConfiguration.USERNAME, IRODSConfiguration.PASSWORD, 
				base , IRODSConfiguration.MCAT_ZONE , IRODSConfiguration.DEFAULTSTORAGERESOURCE );
	}
	
	public static void main (String[] args ) throws NullPointerException, IOException{
		System.out.println (deleteFile ( "/CCDBProdZone/home/CCDB_DATA_USER/acquisition/project_10143/microscopy_2490/data/tmp25/membranes/output003.tif"  ) );
	}
}
